#!/usr/bin/env python
# coding: utf-8
"""
准备工作：需要把705upgrade目录放在脚本执行的路径下
"""

import re
import os
import time
import datetime
import string
from upgrade_file import *

log_node_summary = "upgrade_summary"
log_node_fail = "upgrade_fail"
log_node_success = "upgrade_success"
log_file_not_existed = "the file:%s isn't existed\n"

log_connect_fail = "connect ip:%s failed\n"
log_connect_slot_fail = "connect ip:%s slot:%s failed\n"

log_get_fail = "get ip:%s failed\n"
log_put_fail = "put ip:%s slot:%s failed\n"
log_upgrade_fail = "upgrade ip:%s slot:%s failed\n"

log_connect_success = "connect ip:%s success\n"
log_register_value_success = "ip:%s slot:%s register:%d value:%d success\n"

log_get_success = "get ip:%s success\n"
log_put_success = "put ip:%s slot:%s success\n"
log_upgrade_success = "upgrade ip:%s slot:%s success\n"
log_non64f01_success = "ip:%s have no n64f01 card or no n64f01 card need to upgrade CPLD\n"

log_summary_success = "upgrade cpld ip:%s success\n"
log_summary_fail = "upgrade cpld ip:%s fail\n"



class TestCase(UpgradeSoftware):
    """
    TestCase
    """
    OPTIONS = [
        {
            'opt' : '--cfgfile',
            'dest': 'cfgfile',
            'metavar' : 'CFGFILE',
            'help' : 'the file of ip list configuration',
            'required' : False,
            'default' : "ip.txt"
        },
        {
            'opt' : '--cpldfile',
            'dest': 'cpldfile',
            'metavar' : 'CPLDFILE',
            'help' : 'the file of N64F01 CPLD',
            'required' : False,
            'default' : "74N6416F01V2_A1.vme"
        },        
    ]     
    
    def info_init(self):
        self.info_dic = {}
        
        self.log_node_summary = log_node_summary
        self.log_node_fail = log_node_fail
        self.log_node_success = log_node_success
        
        self.log_file_not_existed = log_file_not_existed 
        self.log_connect_fail = log_connect_fail
        self.log_get_fail = log_get_fail
        self.log_put_fail = log_put_fail
        self.log_upgrade_fail = log_upgrade_fail
        self.log_connect_slot_fail = log_connect_slot_fail
        self.log_register_value_success = log_register_value_success
        
        self.log_connect_success = log_connect_success
        self.log_get_success = log_get_success
        self.log_put_success = log_put_success
        self.log_upgrade_success = log_upgrade_success
        self.log_non64f01_success = log_non64f01_success
        
        self.log_summary_success = log_summary_success
        self.log_summary_fail = log_summary_fail
              
        return True 
    
    #以node为关键字，把信息保存到info_dic[node]中。
    def info_show(self, node, info):
        if not self.info_dic.has_key(node):
            self.info_dic[node] = ""
        self.info_dic[node] += info + '\n'        
        return True    
            
    def info_file_save(self, ip):
        path = os.getcwd()+'//'
        
        for node in self.info_dic:
            info_list = open(path+node+'_'+self.worktime+'.txt','a')            
            info_list.write(self.info_dic[node])
            info_list.close()
            
        return True
    
    def get_iplist(self):
        iplist_filted = []                
        if os.path.isfile(os.getcwd()+r'/'+ self.iplistfile):
            iplist = open(os.getcwd()+r'/'+ self.iplistfile)            
        else:
            self.info_show(self.log_node_fail, self.log_file_not_existed%(self.iplistfile))            
            return iplist_filted 
        
        for line in iplist:
            if re.match(r'^\s*$', line) is not None : continue # 忽略空白行
            if re.match(r'^\s*#', line) is not None : continue # 忽略注释行            
            iplist_filted.append(line.strip('\n'))        
            
        iplist.close()
        
        return iplist_filted
    
    def get_upgrade_slot_dic(self, upgrade_file_dic):
        if upgrade_file_dic is None:
            return {}
        
        slot_list = [5,6,7,8]
                    
        rtn = self.tnxxx.send_rtn_str("show card", self.get_ne_ip(0), 0, CLI_PORT)
        card_info_list = re.findall(r"slot:\s+(\d+)\s+(?:--More--\s+)?stat:\s+\w+\s+(?:--More--\s+)?Card:\s+(\w+)\s+", rtn, re.I)
        upgrade_slot_dic = {}
        for card_info in card_info_list:
            slot = int(card_info[0])
            if slot not in slot_list : continue            
           
            card_name = card_info[1].upper()
            if not upgrade_file_dic.has_key(card_name) : continue
                        
            #获取0xb（PCB版本）寄存器的值
            rtn = self.tnxxx.send_rtn_str("*(0xa0000000+0xb*4)&0xf", self.get_ne_ip(0), slot, DEV_PORT)                       
            rtn_str = None
            rtn_str = re.search(r'= \d+',rtn)
            if None == rtn_str:
                self.info_show(self.log_node_fail, log_connect_slot_fail%(self.get_ne_ip(0),slot))
                continue
            else:
                pcb_value = rtn_str.group()[2:]
                self.info_show(self.log_node_success, log_register_value_success%(self.get_ne_ip(0),slot,11,int(pcb_value)))
                
            #获取0x4,0x5（CPLD版本）寄存器的值
            rtn = self.tnxxx.send_rtn_str("*(0xa0000000+0x4*4)&0xff", self.get_ne_ip(0), slot, DEV_PORT)                       
            rtn_str = None
            rtn_str = re.search(r'= \d+',rtn)
            if None == rtn_str:
                self.info_show(self.log_node_fail, log_connect_slot_fail%(self.get_ne_ip(0),slot))
                continue
            else:
                cpldbig_value = rtn_str.group()[2:]
                self.info_show(self.log_node_success, log_register_value_success%(self.get_ne_ip(0),slot,4,int(cpldbig_value)))
                
            rtn = self.tnxxx.send_rtn_str("*(0xa0000000+0x5*4)&0xff", self.get_ne_ip(0), slot, DEV_PORT)                       
            rtn_str = None
            rtn_str = re.search(r'= \d+',rtn)
            if None == rtn_str:
                self.info_show(self.log_node_fail, log_connect_slot_fail%(self.get_ne_ip(0),slot))
                continue
            else:
                cpldsmall_value = rtn_str.group()[2:]
                self.info_show(self.log_node_success, log_register_value_success%(self.get_ne_ip(0),slot,5,int(cpldsmall_value)))
                
            if not (int(pcb_value) >=2 and int(cpldbig_value) != 0x11 and int(cpldsmall_value) != 0x1):
                continue
            
            if not upgrade_slot_dic.has_key(card_name):
                upgrade_slot_dic[card_name] = []
            upgrade_slot_dic[card_name].append(slot)
        return upgrade_slot_dic
       
    def _execute(self):                        
        self.info_init()
        
        worktime = str(datetime.datetime.now())
        self.worktime = worktime[:4]+worktime[5:7]+worktime[8:10]+'_'+worktime[11:13]+worktime[14:16]+worktime[17:19]
        self.iplistfile = self.options.cfgfile
        self.cpldfile = self.options.cpldfile
        self.work_path = os.getcwd()
        
        upgrade_file_dic = {
            "N64F01"  : [
            [r"/tffs/sys", r"74N6416F01V2_A1.vme",           self.work_path,   self.cpldfile],
        ],
}
        
        ip_list = self.get_iplist()         
        
        for ip in ip_list:            
            self.set_ne_ip(0, ip)            
            upgrade_slot_dic = self.get_upgrade_slot_dic(upgrade_file_dic)
            
            query_masterppc_cmd = '''$.dbgcli.0.Cmd "queryasyn valid 1, NeStat, (MasterPPC), *"'''
            rtn_str = None
            rtn_str = self.tnxxx.send_rtn_str(query_masterppc_cmd, ip, 0, MTN_PORT)
            if [] == re.findall('success', rtn_str):         
                self.info_show(self.log_node_fail, self.log_connect_fail%(ip))
                self.info_show(self.log_node_summary, self.log_summary_fail%(ip)) 
                continue
            else:
                masterppc = int(re.findall('\d',rtn_str)[0])
                    
            if {} == upgrade_slot_dic:
                self.info_show(self.log_node_success, self.log_non64f01_success%(ip)) 
                self.info_show(self.log_node_summary, self.log_summary_success%(ip)) 
                continue
            
            if not self.upgrade_files(upgrade_file_dic, upgrade_slot_dic, masterppc):                
                self.info_show(self.log_node_summary, self.log_summary_fail%(ip))
            else:
                self.info_show(self.log_node_summary, self.log_summary_success%(ip)) 
           
           
        worktime = str(datetime.datetime.now())
        self.worktime_end = worktime[:4]+worktime[5:7]+worktime[8:10]+'_'+worktime[11:13]+worktime[14:16]+worktime[17:19]
        
        self.info_show(log_node_summary, "The upgrade cpld operation begin time %s "%(self.worktime))
        self.info_show(log_node_summary, "The upgrade cpld operation end time %s "%(self.worktime_end))
        
        ip = '0.0.0.0'
        self.info_file_save(ip) 
        return True
    
if __name__ == "__main__" :
    case = TestCase()
    case.execute()